<?php

class Rss1Parser implements IRssParser
{
    const CUSTOM_NAMESPACE_PREFIX = "x";

    public function __construct(DOMDocument $rssXmlObject)
    {
        $this->xPathHelper = new XPathHelper($rssXmlObject);
        $this->RegisterCustomNamespacePrefix();
    }

    public function GetMainNode()
    {
        $query = $this->AddCustomPrefix("channel");
        return $this->xPathHelper->GetNode($query);
    }

    public function GetItemNodes()
    {
        $query = $this->AddCustomPrefix("item");
        return $this->xPathHelper->GetNodes($query);
    }

    public function GetTitle($node)
    {
        return $this->GetTextByPrefixedQuery("title", $node);
    }

    public function GetDescription($node)
    {
        $description = $this->GetTextByPrefixedQuery("description", $node);
        if ( !empty($description) )
        {
            $descriptionParser = new PostContentParser($description);
            $description = $descriptionParser->GetPureContent();
        }
        return $description;
    }

    public function GetDate($node)
    {
        $date = ( $node->lookupNamespaceURI("dc") ) ? $this->GetText("dc:date", $node) : "";
        return $date;
    }

    public function GetLink($node)
    {
        return $this->GetTextByPrefixedQuery("link", $node);
    }

    public function GetAuthor($node)
    {
        $author = ( $node->lookupNamespaceURI("dc") ) ? $this->GetText("dc:creator", $node) : "";
        return $author;
    }

    public function GetPostContent($node)
    {
        $content = '';
        $rawContent = $this->GetRawContent($node);
        if ( !empty($rawContent) )
        {
            $postContentParser = new PostContentParser($rawContent);
            $content = $postContentParser->GetPureContent();
        }
        return $content;
    }

    public function GetPostImage($node, $sourceUrl)
    {
        $image = null;
        $description = $this->GetDescription($node);
        if ( !empty($description) )
        {
            $descriptionParser = new PostContentParser($description);
            $image = $descriptionParser->GetPostImage($sourceUrl);
        }

        $rawContent = $this->GetRawContent($node);
        if ( !empty($rawContent) )
        {
            $postContentParser = new PostContentParser($rawContent);
            if ($image == null)
            {
                $image = $postContentParser->GetPostImage($sourceUrl);
            }
        }
        return $image;
    }

    public function GetCategories( $node )
    {
        $categories = array();
        if ( $node->lookupNamespaceURI("dc") )
        {
            $categoryNodes = $this->xPathHelper->GetNodes("dc:subject", $node);
            foreach ( $categoryNodes as $categoryNode )
            {
                $categoryTitle = $this->GetText(".", $categoryNode);
                $rssCategory = new RssCategory();
                $rssCategory->SetTitle($categoryTitle);
                array_push($categories, $rssCategory);
            }
        }
        return $categories;
    }

    private function GetRawContent( $node )
    {
        $rawContent = ( $node->lookupNamespaceURI("content") ) ? $this->GetText("content:encoded", $node) : "";
        return $rawContent;
    }

    /** Registers custom namespace prefix with url defined in a document.
    *   This workaround is needed to enable XPath queries within rss 1.0 documents, otherwise they will return null.
    *
    */
    private function RegisterCustomNamespacePrefix()
    {
        $nsUri = $this->xPathHelper->GetNode(".")->lookupnamespaceURI(null);
        $this->xPathHelper->xpath->registerNamespace(self::CUSTOM_NAMESPACE_PREFIX, $nsUri);
    }

    /** Wrapper for XPathHelper::GetTextByPrefixedQuery method
    *
    */
    private function GetText( $expr, $node = null )
    {
        $result = $this->xPathHelper->GetText( $expr, $node );
        return ( $result !== null ) ? $result : "";
    }

    /** Wrapper for XPathHelper::GetTextByPrefixedQuery method
     *  adds custom namespace prefix to queries
     */
    private function GetTextByPrefixedQuery( $expr, $node = null )
    {
        $expr = $this->AddCustomPrefix( $expr );
        $result = $this->xPathHelper->GetText( $expr, $node );
        return ( $result !== null ) ? $result : "";
    }

    /** Adds custom prefix to XPath query where it is needed
     *  @return query with prefix
     */
    private function AddCustomPrefix( $query )
    {
        $query = preg_replace("/\/(\w+)/", "/" . self::CUSTOM_NAMESPACE_PREFIX . ":$1", $query);
        $query = preg_replace("/\|\s+(\w+)/", "| " . self::CUSTOM_NAMESPACE_PREFIX . ":$1", $query);
        return preg_replace("/^\w+/", self::CUSTOM_NAMESPACE_PREFIX . ":$0", $query);
    }
}

?>